<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul id="list-with-big-data">1000个好友</ul>
</body>
<script>
    const consumser =(item,i)=>{
        const li = document.createElement('li')
        li.textContent =i;
        document.body.appendChild(li);
    }
    const chunkSplitor1 = (task)=>{
        setTimeout(()=>{
            task((time)=>time<16);
        },2000)
    }
    performChunk(1000,consumser,chunkSplitor1)
    // performChunk(1000,consumser)
/**
 * 
 * @param {*} datas  
 * @param { Function } consumer  
 * @param { Function } [chunkSplitor]
 * @returns 
 * @example 
 *   const consumer = (item, i) => {
 *     ...执行内容
 *   }
 *   const chunkSplitor = (task) => {
 *     setTimeout(() => {
 *       task( (time) => time<16 ) 接收一个函数，返回一个布尔值，true表示有时间
 *     }, 30)
 *   }
 * 
 *   可以执行某一个任务指定次数，
 *   也可以提供一个执行任务数组，提供分块规则，使其分快执行
 *   performChunk(datas, consumer, chunkSplitor) chunkSplitor 可选参数
 */

function performChunk(datas, consumer, chunkSplitor) {
    // 参数归一化处理
    if(typeof datas == 'number'){ 
      datas = new Array(datas)
    }
    if(!chunkSplitor && globalThis.requestIdleCallback){
        chunkSplitor = (task) => {
            requestIdleCallback(idle => {
                task( () => idle.timeRemaining() > 0 )
            })
        }
    }
    if(datas.length === 0){
        return;
    }
    let i = 0;     //目前应该取出的任务下标

    // 执行一块任务
    function _run(){
       if(i === datas.length){
        return;
       }

       // 函数要求 1.如何分块执行，2.是否还有执行时间
       chunkSplitor((hasTime) => {
        let now = Date.now(); //1.计算当前时间的毫秒数 new Date().getTime()
        // 发现还有空余时间
         while (hasTime(Date.now() - now) && i<datas.length){
            const item = datas[i]; //Grab a task from the array.
            
            // ...需要执行的任务... 将任务放到这里执行
            consumer(item, i)

            i++
         }
         _run()
       })
    //    requestIdleCallback(idle => {
    //     // 发现还有空余时间
    //      while (idle.timeRemaining() > 0 && i<datas.length){
    //         const item = datas[i]; //Grab a task from the array.
            
    //         // ...需要执行的任务... 将任务放到这里执行
    //         consumer(item, i)

    //         i++
    //      }
    //      _run()
    //    })
    }

    _run()  // Call the function to begin the chunk.
}

</script>
</html>